import { _decorator, CCString, Component, EventTarget, ImageAsset, instantiate, Label, Layout, Node, Prefab, Sprite, SpriteFrame, Widget, tween, UIOpacity } from 'cc';
import { Logger } from 'db://assets/util';
import { PropEvent, PropItem } from './prop/PropItem';
import { ResourceLoad, ServiceLocator } from '../service';
import { Chapter } from 'db://assets/store';
import { EventType, STATE } from 'db://assets/enum';
const { ccclass, property, menu } = _decorator;

@ccclass('InteractiveFrame')
@menu('frame/Interactive')
export class InteractiveFrame extends Component {
    #logger = new Logger("交互容器::InteractiveFrame");
    #service = ServiceLocator;
    #resourceLoader = new ResourceLoad()

    @property(Layout)
    line1PropLayout: Layout;

    @property(Layout)
    line2PropLayout: Layout;

    @property(Label)
    title: Label

    @property(Label)
    desc: Label

    @property(Prefab)
    chargeProp: Prefab

    @property(Prefab)
    normalProp: Prefab

    $active: LDChapter.ChildFrame

    get titleContainer() {
        return this.title.getComponent(Widget)
    }

    get opacity() {
        return this.getComponent(UIOpacity)
    }

    get chapter() {
        return this.#service.get<Chapter>(STATE.CHAPTER)
    }

    get event() {
        return this.#service.get<EventTarget>(STATE.EVENT)
    }

    private _onelineTitle = 752;
    private _twolineTitle = 1070;

    protected onEnable(): void {
        this.node.on('prop', this.onPropClick, this)
    }

    protected onDisable(): void {
        this.node.off('prop')
    }

    onPropClick(event: PropEvent) {
        this.#logger.debug("#onPropClick", event.detail)
        this.$active = event.detail
        if (this.line1PropLayout.node.active) {
            for (const propNode of this.line1PropLayout.node.children) {
                const propItem = propNode.getComponent(PropItem)
                if (propItem.prop.id !== event.detail.id) {
                    propNode.getComponent(Sprite).spriteFrame = propItem.normalBG
                }
            }
        }

        if (this.line2PropLayout.node.active) {
            for (const propNode of this.line2PropLayout.node.children) {
                const propItem = propNode.getComponent(PropItem)
                if (propItem.prop.id !== event.detail.id) {
                    propNode.getComponent(Sprite).spriteFrame = propItem.normalBG
                }
            }
        }
    }

    start() {
        this.#logger.debug("#start")
    }

    async showInteractiveFrame(interactiveContent: LDContent.InteractiveContent, children: LDChapter.ChildFrame[]) {
        this.#logger.debug("#showInteractiveFrame", interactiveContent, children);
        if (children.length > 2) await this.init2lineContainer(children);
        else await this.init1lineContainer(children);
        this.node.active = true;
    }

    async init2lineContainer(children: LDChapter.ChildFrame[]) {
        for (const index in children) {
            const prop = children[index]
            this.#logger.debug("init2lineContainer>prop", prop)
            if (+index < 2) {
                const propNode = await this.initPropItem(prop)
                this.line2PropLayout.node.addChild(propNode)
            } else {
                const propNode = await this.initPropItem(prop)
                this.line1PropLayout.node.addChild(propNode)
            }
        }

        this.titleContainer.bottom = this._twolineTitle;
        this.line1PropLayout.node.active = true;
        this.line2PropLayout.node.active = true;
    }

    async init1lineContainer(children: LDChapter.ChildFrame[]) {
        for (const index in children) {
            const prop = children[index]
            this.#logger.debug("init1lineContainer>prop", prop)
            this.line2PropLayout.node.addChild(await this.initPropItem(prop))
        }
        this.titleContainer.bottom = this._onelineTitle;
        this.line2PropLayout.node.active = true;
    }

    async initPropItem(prop: LDChapter.ChildFrame): Promise<Node> {
        const isCharge = (prop.content as LDContent.OptionContent).diamond && !(prop.content as LDContent.OptionContent).isFree
        const node = instantiate(isCharge ? this.chargeProp : this.normalProp)
        const propitem = node.getComponent(PropItem)
        propitem.prop = prop
        if ((prop.content as LDContent.OptionContent).materialId) {
            const resource = this.chapter.getResource((prop.content as LDContent.OptionContent).materialId)
            const propImg = await this.#resourceLoader.loadRemote<ImageAsset>(resource.ossUrl)
            propitem.propNode.spriteFrame = SpriteFrame.createWithImage(propImg)
        }
        if (isCharge) propitem.priceNode.string = (prop.content as LDContent.OptionContent).diamond.toString()
        propitem.labelNode.string = (prop.content as LDContent.OptionContent).option

        return node
    }

    async onConfirm() {
        this.#logger.debug('#onConfirm', this.$active)
        if (this.$active) {
            await this.fadeOut()
            this.node.active = false
            this.node.emit('confirm')
            this.event.emit(EventType.NEXT_FRAME, this.$active.nextId)
        }
    }

    async fadeIn() {
        return new Promise(resolve => tween(this.opacity)
            .to(0.625, { opacity: 255 })
            .call(resolve)
            .start())
    }

    async fadeOut() {
        return new Promise(resolve => tween(this.opacity)
            .to(0.625, { opacity: 0 })
            .call(resolve)
            .start())
    }
}

